package com.example.webfluxdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;


/**
 * https://www.cnblogs.com/felordcn/p/13395095.html
 *
 * Mono 常用的方法有：
 *
 *     Mono.create()：使用 MonoSink 来创建 Mono
 *     Mono.justOrEmpty()：从一个 Optional 对象或 null 对象中创建 Mono。
 *     Mono.error()：创建一个只包含错误消息的 Mono
 *     Mono.never()：创建一个不包含任何消息通知的 Mono
 *     Mono.delay()：在指定的延迟时间之后，创建一个 Mono，产生数字 0 作为唯一值
 * ————————————————
 * 版权声明：本文为CSDN博主「架构师-尼恩」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
 * 原文链接：https://blog.csdn.net/crazymakercircle/article/details/112977951
 *
 *
 * 如果知道 Publisher 是 0 或 1 个，则用 Mono。
 * Flux 最值得一提的是 fromIterable 方法。
 * fromIterable(Iterable<? extends T> it) 可以发布 Iterable 类型的元素。
 * 当然，Flux 也包含了基础的操作：map、merge、concat、flatMap、take，这里就不展开介绍了
 * ————————————————
 * 版权声明：本文为CSDN博主「架构师-尼恩」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
 * 原文链接：https://blog.csdn.net/crazymakercircle/article/details/112977951
 */
@RestController
@RequestMapping("/test")
public class ReactiveClientUserController {
    @Autowired
    private UserRepository userRepository;


    /**
     * 这里为了检验默认api 就不分层了
     *
     * @param userId the user id
     * @return the mono
     */
    @GetMapping("/{userId}")
    public Mono<User> findUserById(@PathVariable Long userId) {
        return userRepository.findById(userId);
    }

    //以数组形式一次性返回数据
    @GetMapping("/list")
    public Flux<User> listAllUser(){
        return userRepository.findAll();
    }

    //以SSE形式流一样返回数据
    //https://blog.csdn.net/mmx8112/article/details/85637025?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control
    @GetMapping(value = "/list/sse",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> listAllUserSSE(){
        return userRepository.findAll();
    }

    /**
     * Mono 和 Flux 适用于两个场景，即：
     * Mono：实现发布者，并返回 0 或 1 个元素，即单对象。
     * Flux：实现发布者，并返回 N 个元素，即 List 列表对象。
     * 有人会问，这为啥不直接返回对象，比如返回 City/Long/List。
     * 原因是，直接使用 Flux 和 Mono 是非阻塞写法，相当于回调方式。
     * 利用函数式可以减少了回调，因此会看不到相关接口。这恰恰是 WebFlux 的好处：集合了非阻塞 + 异步
     */
//————————————————
//    版权声明：本文为CSDN博主「架构师-尼恩」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
//    原文链接：https://blog.csdn.net/crazymakercircle/article/details/112977951
    @GetMapping("/echo")
    public Mono<String> sayHelloWorld() {
        return Mono.just("Echo!");
    }




}
